package com.softserveinc.moviedbapp.adapter;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RatingBar;
import android.widget.TextView;

import com.softserveinc.moviedbapp.R;
import com.softserveinc.moviedbapp.fragment.MovieListFragment.OnMovieSelectedListener;
import com.softserveinc.moviedbapp.model.Movie;

import java.util.ArrayList;

public class MovieAdapter extends ArrayAdapter<Movie[]> {

	private static final String TAG = MovieAdapter.class.getSimpleName();
	private static final boolean DEBUG = true;

	private static final int FIRST_IN_A_PAIR = 0;
	private static final int SECOND_IN_A_PAIR = 1;
	private static final int RATING_DIVIDER = 2;

	private ArrayList<Movie[]> movies;
	private OnMovieSelectedListener onMovieSelectedListener;
	private boolean busy = false;

	private LinearLayout row;
	private OnItemClickListener listenerTwo;
	private OnItemClickListener listenerOne;

	public MovieAdapter(final Context context, final int textViewResourceId, final ArrayList<Movie[]> movies) {
		super(context, textViewResourceId, movies);
		this.movies = movies;
		listenerOne = new OnItemClickListener(FIRST_IN_A_PAIR);
		listenerTwo = new OnItemClickListener(SECOND_IN_A_PAIR);
	}

	public static class ViewHolder {
		public LinearLayout gridItemLayout;
		public TextView movieName;
		public RatingBar movieRatingBar;
		public ImageView moviePoster;
		public ProgressBar moviePosterProgress;
	}

	@Override
	public View getView(final int position, final View convertView, final ViewGroup parent) {
		if (DEBUG) {
			Log.e(TAG, "getView() position = " + position);
		}
		row = (LinearLayout) convertView;
		ViewHolder viewHolderOne;
		ViewHolder viewHolderTwo;

		/* populate each row of the list */
		if (row == null) {
			LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			row = (LinearLayout) inflater.inflate(R.layout.grid_item_row, null);
			LinearLayout movieView_1 = (LinearLayout) inflater.inflate(R.layout.grid_movie_holder, null);
			LinearLayout movieView_2 = (LinearLayout) inflater.inflate(R.layout.grid_movie_holder, null);

			/* use view holder so we don't have to findViewById for every single view always */
			viewHolderOne = new ViewHolder();
			viewHolderOne.gridItemLayout = (LinearLayout) movieView_1.findViewById(R.id.grid_item);
			viewHolderOne.movieName = (TextView) movieView_1.findViewById(R.id.movieName);
			viewHolderOne.movieRatingBar = (RatingBar) movieView_1.findViewById(R.id.grid_ratingBar);
			viewHolderOne.moviePoster = (ImageView) movieView_1.findViewById(R.id.grid_poster);
			viewHolderOne.moviePosterProgress = (ProgressBar) movieView_1.findViewById(R.id.posterProgressBar);

			viewHolderTwo = new ViewHolder();
			viewHolderTwo.gridItemLayout = (LinearLayout) movieView_2.findViewById(R.id.grid_item);
			viewHolderTwo.movieName = (TextView) movieView_2.findViewById(R.id.movieName);
			viewHolderTwo.movieRatingBar = (RatingBar) movieView_2.findViewById(R.id.grid_ratingBar);
			viewHolderTwo.moviePoster = (ImageView) movieView_2.findViewById(R.id.grid_poster);
			viewHolderTwo.moviePosterProgress = (ProgressBar) movieView_2.findViewById(R.id.posterProgressBar);

			row.addView(movieView_1, 0);
			row.addView(movieView_2, 2);
			row.setTag(R.id.TAG_FIRST_VIEWHOLDER, viewHolderOne);
			row.setTag(R.id.TAG_SECOND_VIEWHOLDER, viewHolderTwo);
		} else {
			viewHolderOne = (ViewHolder) row.getTag(R.id.TAG_FIRST_VIEWHOLDER);
			viewHolderTwo = (ViewHolder) row.getTag(R.id.TAG_SECOND_VIEWHOLDER);
		}
		Movie[] moviePair = movies.get(position);
		setMovie(viewHolderOne, moviePair[FIRST_IN_A_PAIR]);
		setMovie(viewHolderTwo, moviePair[SECOND_IN_A_PAIR]);

		if (!busy) {
			viewHolderOne.gridItemLayout.setTag(position);
			viewHolderOne.gridItemLayout.setOnClickListener(listenerOne);
			viewHolderTwo.gridItemLayout.setTag(position);
			viewHolderTwo.gridItemLayout.setOnClickListener(listenerTwo);
		}
		return row;
	}

	private void setMovie(final ViewHolder viewHolder, final Movie movie) {
		if (movie != null) {
			/* set the movie title */
			viewHolder.movieName.setText(movie.getName() + getReleaseYear(movie.getReleased()));
			/* set the rating bar value */
			viewHolder.movieRatingBar.setRating(((float) movie.getRating()) / RATING_DIVIDER);

			/* set the poster if not busy, hide otherwise */
			if (!busy) {
				showPoster(viewHolder, movie);
			} else {
				recyclePoster(viewHolder, movie);
			}
		}
	}

	private String getReleaseYear(final String released) {
		return (" (" + released.substring(0, 4) + ")");
	}

	private void showPoster(final ViewHolder viewHolder, final Movie movie) {
		if (DEBUG) {
			Log.e(TAG, "showPoster() movie = " + movie.getName());
		}
		if (!movie.isPosterRecycled()) {
			viewHolder.moviePoster.setImageBitmap(movie.getPosterBitmap());
			viewHolder.moviePoster.setVisibility(View.VISIBLE);
			viewHolder.moviePosterProgress.setVisibility(View.GONE);
		} else {
			viewHolder.moviePoster.setVisibility(View.GONE);
			viewHolder.moviePosterProgress.setVisibility(View.VISIBLE);
		}
	}

	private void recyclePoster(final ViewHolder viewHolder, final Movie movie) {
		if (!movie.isPosterRecycled()) {
			if (DEBUG) {
				Log.i(TAG, "vis p gonna recycle recyclePoster() " + movie.getName());
			}
			movie.getPosterBitmap().recycle();
			movie.setPosterRecycled(true);
		}
		viewHolder.moviePoster.setVisibility(View.GONE);
		viewHolder.moviePosterProgress.setVisibility(View.VISIBLE);
	}

	public boolean isBusy() {
		return busy;
	}

	public void setBusy(final boolean busy) {
		this.busy = busy;
	}

	public void setOnMovieSelectedListener(final OnMovieSelectedListener onMovieSelectedListener) {
		this.onMovieSelectedListener = onMovieSelectedListener;
	}

	public void recycleLastVisiblePosters(final int firstVisiblePosition, final int lastVisiblePosition) {
		if (DEBUG) {
			Log.i(TAG, "vis p recycleLastVisiblePosters firstVisiblePosition " + firstVisiblePosition
					+ " lastVisiblePosition " + lastVisiblePosition);
		}
		for (int i = firstVisiblePosition; i <= lastVisiblePosition; i++) {
			Movie[] moviePair = movies.get(i);
			if (!moviePair[FIRST_IN_A_PAIR].isPosterRecycled()) {
				if (DEBUG) {
					Log.i(TAG,
							"vis p gonna recycle recycleLastVisiblePosters() " + moviePair[FIRST_IN_A_PAIR].getName());
				}
				moviePair[FIRST_IN_A_PAIR].getPosterBitmap().recycle();
				moviePair[FIRST_IN_A_PAIR].setPosterRecycled(true);
			}
			if (!moviePair[SECOND_IN_A_PAIR].isPosterRecycled()) {
				if (DEBUG) {
					Log.i(TAG,
							"vis p gonna recycle recycleLastVisiblePosters() " + moviePair[SECOND_IN_A_PAIR].getName());
				}
				moviePair[SECOND_IN_A_PAIR].getPosterBitmap().recycle();
				moviePair[SECOND_IN_A_PAIR].setPosterRecycled(true);
			}
		}
	}

	private class OnItemClickListener implements OnClickListener {

		private int position;
		private int whichOne;

		OnItemClickListener(final int whichOne) {
			this.whichOne = whichOne;
		}

		@Override
		public void onClick(final View v) {
			if (!busy) {
				position = (Integer) v.getTag();
				onMovieSelectedListener.onMovieSelected(movies.get(position)[whichOne]);
			}
		}
	}
}
